package com.dayuanit.dy16.atm.boatm.service.impl;

import com.dayuanit.dy16.atm.boatm.dto.SalaryDTO;
import com.dayuanit.dy16.atm.boatm.dto.SalaryDetailDTO;
import com.dayuanit.dy16.atm.boatm.entity.Card;
import com.dayuanit.dy16.atm.boatm.entity.Flow;
import com.dayuanit.dy16.atm.boatm.entity.Salary;
import com.dayuanit.dy16.atm.boatm.entity.SalaryDetail;
import com.dayuanit.dy16.atm.boatm.enums.SalaryDetailStatus;
import com.dayuanit.dy16.atm.boatm.enums.SalaryStatus;
import com.dayuanit.dy16.atm.boatm.exception.BizException;
import com.dayuanit.dy16.atm.boatm.handler.ExcelDataListener;
import com.dayuanit.dy16.atm.boatm.mapper.CardMapper;
import com.dayuanit.dy16.atm.boatm.mapper.FlowMapper;
import com.dayuanit.dy16.atm.boatm.mapper.SalaryDetailMapper;
import com.dayuanit.dy16.atm.boatm.mapper.SalaryMapper;
import com.dayuanit.dy16.atm.boatm.service.ISalaryService;
import com.dayuanit.dy16.atm.boatm.util.DateUtils;
import com.dayuanit.dy16.atm.boatm.util.MoneyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SalaryServiceImpl implements ISalaryService {

    @Autowired
    private SalaryMapper salaryMapper;

    @Autowired
    private SalaryDetailMapper salaryDetailMapper;

    @Autowired
    private CardMapper cardMapper;

    @Autowired
    private FlowMapper flowMapper;

    @Override
    public void updateSalaryFile(long salaryId, String fileName) {
        Salary salary = salaryMapper.selectByPrimaryKey(salaryId);
        if (null == salary) {
            throw new BizException("参数错误");
        }

        int rows = salaryMapper.modifySalaryFile(salaryId, fileName, salary.getStatus(), SalaryStatus.wait_save.getK());
        if (rows != 1) {
            throw new BizException("上传失败");
        }
    }

    @Override
    public void createSalary(String salaryTitle, String remark, long userId) {
        if (StringUtils.isBlank(salaryTitle)) {
            throw new BizException("请输入标题");
        }
        Salary salary = new Salary();

        salary.setCreateTime(new Date());
        salary.setExcelTitleName(salaryTitle);
        salary.setModifyTime(salary.getCreateTime());
        salary.setRemark(remark);
        salary.setStatus(SalaryStatus.wait_upload.getK());
        salary.setUserId(userId);
        salaryMapper.insert(salary);
    }

    @Override
    public List<SalaryDTO> loadSalarys() {
        List<Salary> salaries = salaryMapper.listSalary(null);
        List<SalaryDTO> dtos = new ArrayList<>(salaries.size());
        for (Salary salary : salaries) {
            SalaryDTO salaryDTO = new SalaryDTO();
            dtos.add(salaryDTO);

            salaryDTO.setCreateTime(DateUtils.date2String(salary.getCreateTime()));
            salaryDTO.setFileTitle(salary.getExcelTitleName());
            salaryDTO.setRemark(salary.getRemark());
            salaryDTO.setSalaryId(salary.getId());
            salaryDTO.setStatusValue(SalaryStatus.find(salary.getStatus()).getV());
            salaryDTO.setStatus(salary.getStatus());
        }
        return dtos;
    }

    @Transactional
    @Override
    public void saveSalaryFileData(List<ExcelDataListener.SalaryExcelData> datas, long salaryId) {

        Salary salary = salaryMapper.selectByPrimaryKey(salaryId);
        if (salary.getStatus() != SalaryStatus.wait_save.getK()) {
            return;
        }

        List<SalaryDetail> details = new ArrayList<>(datas.size());

        for (ExcelDataListener.SalaryExcelData s : datas) {
            SalaryDetail salaryDetail = new SalaryDetail();
            salaryDetail.setAmount(s.getAmount());
            salaryDetail.setCardNum(s.getCardNum());
            salaryDetail.setSalaryId(salaryId);
            salaryDetail.setStatus(1);
            details.add(salaryDetail);
        }

        salaryDetailMapper.batchSaveSalary(details);

        // 更新状态
        int rows = salaryMapper.updateStatus(salaryId, salary.getStatus(), SalaryStatus.wait_verify.getK());
        if (rows != 1) {
            throw new BizException("入库失败");
        }
    }

    @Override
    public void submitVerify(long userId, long salaryId) {
        Salary salary = salaryMapper.selectByPrimaryKey(salaryId);
        if (salary == null) {
            throw new BizException("参数错误");
        }

        //要判断原始状态 是否可以改变成目标状态
        if (salary.getStatus() != SalaryStatus.submit_verify.getK()) {
            throw new BizException("无法提交审核");
        }

        int rows = salaryMapper.updateStatus(salaryId, salary.getStatus(), SalaryStatus.wait_verify.getK());
        if (1 != rows) {
            throw new BizException("提交失败");
        }
    }

    @Override
    public void approved(long usreId, long salaryId) {
        Salary salary = salaryMapper.selectByPrimaryKey(salaryId);
        if (salary == null) {
            throw new BizException("参数错误");
        }

        if (salary.getStatus() != SalaryStatus.wait_verify.getK()) {
            throw new BizException("无法审核");
        }

        int rows = salaryMapper.updateStatus(salaryId, salary.getStatus(), SalaryStatus.approved.getK());
        if (1 != rows) {
            throw new BizException("操作失败");
        }

        //用定时器 发工资
    }

    @Transactional
    @Override
    public void payOff(SalaryDetail detail) {
        if (detail.getStatus() != SalaryDetailStatus.wait_pay.getK()) {
            return;
        }

        // 加钱
        Card card = cardMapper.get4LockByCardNumber(detail.getCardNum());
        Integer balance = card.getBalance();

        double amount = Double.parseDouble(detail.getAmount());

        if (amount <= 0 ) {
            return;
        }

        int newBalance = MoneyUtils.plus(card.getBalance(), amount);

        int rows = cardMapper.updateBalance(card.getId(), newBalance, card.getBalance());
        if (1 != rows) {
            throw new BizException("存钱失败");
        }

        Flow flow = new Flow();
        flow.setAmount(detail.getAmount());
        flow.setCardId(card.getId());
        flow.setCreateTime(new Date());
        flow.setFlowType(1);
        flow.setRemark("");
        flow.setUserId(card.getUserId());
        rows = flowMapper.insert(flow);

        if (1 != rows) {
            throw new BizException("存钱失败");
        }

        rows = salaryDetailMapper.updateStatus(detail.getId(), detail.getStatus(), SalaryDetailStatus.pay_success.getK());
        if (1 != rows) {
            throw new BizException("存钱失败");
        }
    }

    @Override
    public void refuse(long userId, long salaryId) {
        Salary salary = salaryMapper.selectByPrimaryKey(salaryId);
        if (salary == null) {
            throw new BizException("参数错误");
        }

        if (salary.getStatus() != SalaryStatus.wait_verify.getK()) {
            throw new BizException("无法审核");
        }

        int rows = salaryMapper.updateStatus(salaryId, salary.getStatus(), SalaryStatus.refuse.getK());
        if (1 != rows) {
            throw new BizException("操作失败");
        }
    }

    @Override
    public List<SalaryDetailDTO> listDetails(long salaryId) {
        List<SalaryDetail> details = salaryDetailMapper.listBySalaryId(salaryId);
        List<SalaryDetailDTO> dtos = new ArrayList<>(details.size());

        for (SalaryDetail detail : details) {
            SalaryDetailDTO salaryDetailDTO = new SalaryDetailDTO();
            dtos.add(salaryDetailDTO);
            salaryDetailDTO.setAmount(detail.getAmount());
            salaryDetailDTO.setCardNum(detail.getCardNum());
            salaryDetailDTO.setDetailId(detail.getId());
            salaryDetailDTO.setStatus(detail.getStatus());
            salaryDetailDTO.setStatusValue(SalaryDetailStatus.find(detail.getStatus()).getV());
        }
        return dtos;
    }
}
